package index;

import heap.RID;
import storage.data.PageID;
import Transaction.Transaction;
import Common.GlobalConst;
import Common.GoggleDB;

public class BTFileScan implements GlobalConst {

	BTFile bfile;

	String btreefilename;

	LeafPage leafpage;

	RID curRid; // position in current leaf; note: this is

	boolean didfirst; // false only before getNext is called

	boolean deletedcurrent; // true after deleteCurrent is called (read by

	// get_next, written by deleteCurrent).

	KeyClass endkey; // if NULL, then go all the way right else, stop when

	// current record > this value. (that is, implement an
	// inclusive range scan -- the only way to do a search
	// for a single value).

	int keyType;

	int maxKeysize;

	public KeyDataEntry getNext(Transaction tx, String table) throws Exception {
		KeyDataEntry entry;
		PageID nextPageID;
		if (leafpage == null) {
			return null;
		}
		//System.out.println("rid:"+"["+curRid.pageNo.pageId+" "+curRid.slotNo);
		if ((deletedcurrent && didfirst) || (!deletedcurrent && !didfirst)) {
			didfirst = true;
			deletedcurrent = false;
			entry = leafpage.getCurrent(curRid, tx, table);
		} else {
			entry = leafpage.getNext(curRid, tx, table);
			//System.out.println("entry:"+entry.key.toString());
		}
		

		while (entry == null) {
			nextPageID = leafpage.getNextPage(tx, table);
			GoggleDB.bufferMgr.unpinPage(leafpage.getCurPage(tx, table), true);
			if (nextPageID.pageId == INVALID) {
				leafpage = null;
				return null;
			}

			leafpage = new LeafPage(nextPageID, keyType, tx, table);

			entry = leafpage.getFirst(curRid, tx, table);
			System.out.println("key:"+entry.key.toString());
		}

		if (endkey != null) {
			//System.out.println("haha:"+endkey.toString());
			if (BT.KeyCompare(entry.key, endkey) > 0) {
				// went past right end of scan
				//System.out.println("entry:"+entry.key);
				GoggleDB.bufferMgr.unpinPage(leafpage.getCurPage(tx, table),
						false);
				leafpage = null;
				return null;
			}
		}

		return entry;
	}

	public void deleteCurrent(Transaction tx, String table) throws Exception {

		KeyDataEntry entry;
		if (leafpage == null) {
			System.out.println("No Record to delete!");
		}

		if ((deletedcurrent == true) || (didfirst == false))
			return;

		entry = leafpage.getCurrent(curRid, tx, table);
		GoggleDB.bufferMgr.unpinPage(leafpage.getCurPage(tx, table), false);
		bfile.Delete(entry.key, ((LeafData) entry.data).getData(), tx, table);
		leafpage = bfile.findRunStart(entry.key, curRid, tx, table);

		deletedcurrent = true;
		return;

	}

	public int keysize() {
		return maxKeysize;
	}

	public void DestroyBTreeFileScan(Transaction tx, String table)
			throws Exception {
		if (leafpage != null) {
			GoggleDB.bufferMgr.unpinPage(leafpage.getCurPage(tx, table), true);
		}
		leafpage = null;
	}

}
